package com.sinosoft.web.easyui.api;

import cn.com.sinux.spring.commons.OrderCollection;
import cn.com.sinux.spring.commons.PropertyCollection;
import cn.com.sinux.spring.exception.BusinessException;
import cn.com.sinux.spring.json.JsonFilter;
import cn.com.sinux.spring.utils.DateUtils;
import cn.com.sinux.spring.utils.PageUtils;
import cn.com.sinux.spring.utils.QueryHelper;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sinosoft.hydra.um.LoginUser;
import com.sinosoft.hydra.um.condition.SearchAttendanceCondition;
import com.sinosoft.hydra.um.condition.SearchOrganizationCondition;
import com.sinosoft.hydra.um.condition.SearchUserCondition;
import com.sinosoft.hydra.um.constant.BaseConstant;
import com.sinosoft.hydra.um.domain.model.DirectoryType;
import com.sinosoft.hydra.um.domain.permission.*;
import com.sinosoft.hydra.um.helper.AuthContextHelper;
import com.sinosoft.hydra.um.helper.LoggerHelper;
import com.sinosoft.hydra.um.services.AttendanceService;
import com.sinosoft.hydra.um.services.DirectoryService;
import com.sinosoft.hydra.um.services.SysOrganizationService;
import com.sinosoft.hydra.um.services.SysUserService;
import com.sinosoft.hydra.um.services.component.dataoutput.ExcelDataWriter;
import com.sinosoft.hydra.um.utils.ExcelUtils;
import com.sinosoft.hydra.um.utils.excel.ColumnConverter;
import com.sinosoft.hydra.um.utils.excel.ExportBuilder;
import com.sinosoft.hydra.um.utils.excel.ExportColumn;
import com.sinosoft.web.common.WebInput;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;

/**
 * Created by lcb on 2016/8/31.
 */
@Controller
@RequestMapping(value = "/api/attendance")
public class SysAttendanceApi {

    @Autowired
    private AttendanceService attendanceService;
    @Autowired
    private SysUserService userService;
    @Autowired
    private DirectoryService directoryService;
    @Autowired
    private SysOrganizationService organizationService;

    //公干和零星事假的天数换算
    private double hourOfDay = 8.0;
    //加班天数换算
    private double hourOfDay1 = 7.0;

    /**
     * 到考勤登记页面
     *
     * @return
     */
    @RequestMapping(value = "toSelfList")
    @RequiresPermissions(value = "attendance:data:selfList")
    public String toSelfList(Model model, @RequestParam(value = "id", required = false) String id) {
//        LoggerHelper.logInfo("查看了考勤登记列表信息");
        SysUserMember user = userService.findOne(id);
        model.addAttribute("user", user);
        model.addAttribute("now", new Date());
        return "hydra_easyui/attendance/selfList";
    }


    /**
     * 到考勤登记页面
     *
     * @return
     */
    @RequestMapping(value = "toApproList")
    @RequiresPermissions(value = "attendance:data:approList")
    public String toApproList(Model model) {
//        LoggerHelper.logInfo("查看了考勤登记列表信息");
        return "hydra_easyui/attendance/approList";
    }

    /**
     * 查询考勤登记列表json
     *
     * @param condition
     * @param pageSize
     * @param pageNumber
     * @return
     */
    @RequestMapping(value = "approList")
    @ResponseBody
    public Object approList(
            SearchAttendanceCondition condition,
            @RequestParam(value = "rows", defaultValue = "10", required = false) Integer pageSize,
            @RequestParam(value = "page", defaultValue = "1", required = false) Integer pageNumber) {
        Pageable pageable = PageUtils.buildPageRequest(pageNumber, pageSize, "createTime", "desc");
        Page<TAttendance> page = attendanceService.findWaitApproAttendances(condition, pageable);
        return page;
    }

    /**
     * 查询考勤登记列表json
     *
     * @param ids
     * @return
     */
    @RequestMapping(value = "approval", method = RequestMethod.POST)
    @ResponseBody
    public Object approval(
            @RequestParam(value = "ids") String ids,
            @RequestParam(value = "approvalType") String type) {
        if (StringUtils.isBlank(ids)) {
            throw new BusinessException("至少需要选择一条记录");
        }
        List<TApproRecord> approRecords = new ArrayList<TApproRecord>();
        for (String id : ids.split(",")) {
            TApproRecord approRecord = new TApproRecord();
            TAttendance attendance = new TAttendance();
            attendance.setId(id);
            approRecord.settAttendance(attendance);
            approRecord.setApproStatus(TApproRecord.PASS.equals(type) ? TApproRecord.PASS : TApproRecord.REFUSE);
            approRecords.add(approRecord);
        }
        attendanceService.approvalAttendances(AuthContextHelper.getLoginUser(),
                approRecords);
        LoggerHelper.logInfo("审核了考勤记录‘{}’", ids);
        return Collections.singletonMap("status", 1);
    }

    /**
     * 到新增考勤登记页面
     *
     * @return
     */
    @RequestMapping(value = "toAdd")
    @RequiresPermissions(value = "attendance:data:add")
    public String toAdd(Model model) {
        model.addAttribute("now", new Date());
        return "hydra_easyui/attendance/add";
    }

    /**
     * 新增考勤登记
     *
     * @param attendance
     * @return
     */
    @RequestMapping(value = "add")
    @ResponseBody
    public Object add(TAttendance attendance,
                      @RequestParam(value = "beginTime1", required = false) Date beginTime1) {
        if (beginTime1 != null) {
            beginTime1 = "am".equals(attendance.getApm()) ?
                    DateUtils.setHours(beginTime1, 8) : DateUtils.setHours(beginTime1, 14);
            attendance.setBeginTime(beginTime1);
        } else {
            attendance.setApm(null);
        }
        TAttendance att = attendanceService.addAttendance(attendance);
        LoggerHelper.logInfo("新增了考勤登记‘{}’", att.getRemark());
        return JsonFilter.doPropertyFilter(att, new PropertyCollection()
                .addProperties("id", "remark"));
    }

    /**
     * 查询考勤登记列表json
     *
     * @param condition
     * @param pageSize
     * @param pageNumber
     * @return
     */
    @RequestMapping(value = "selfList")
    @ResponseBody
    public Object selfList(
            SearchAttendanceCondition condition,
            @RequestParam(value = "rows", defaultValue = "10", required = false) Integer pageSize,
            @RequestParam(value = "page", defaultValue = "1", required = false) Integer pageNumber) {
        Pageable pageable = PageUtils.buildPageRequest(pageNumber, pageSize, "createTime", "desc");
        Page<TAttendance> page = attendanceService.findSelfList(condition, pageable);
        return page;
    }

    /**
     * 批量删除考勤登记
     *
     * @param condition
     * @return
     */
    @RequestMapping(value = "delete")
    @RequiresPermissions(value = "attendance:data:delete")
    @ResponseBody
    public Object delete(SearchAttendanceCondition condition) {
        List<TAttendance> attendances = attendanceService.delAttendances(condition.getIds());
        LoggerHelper.logInfo("删除了考勤登记‘{}’", new LoggerHelper.PropertyReader<TAttendance>(attendances, "remark"));
        return JsonFilter.doPropertyFilter(attendances, new PropertyCollection()
                .addProperties("id", "remark"));
    }

    /**
     * 到编辑考勤登记页面
     *
     * @return
     */
    @RequestMapping(value = "toEndTime")
    @RequiresPermissions(value = "attendance:data:update")
    public String toEndTime(Model model,
                            @RequestParam(value = "id", required = true) String id) {
        TAttendance attendance = attendanceService.getOne(id);
        model.addAttribute("attendance", attendance);
        return "hydra_easyui/attendance/endTime";
    }

    /**
     * 编辑考勤登记结束时间
     *
     * @param attendance
     * @return
     */
    @RequestMapping(value = "endTime")
    @ResponseBody
    public Object endTime(TAttendance attendance) {
        TAttendance att = attendanceService.addEndTime(attendance);
        LoggerHelper.logInfo("编辑了考勤登记‘{}’", att.getRemark());
        return JsonFilter.doPropertyFilter(att, new PropertyCollection()
                .addProperties("id", "remark"));
    }

    /**
     * 到编辑考勤记录页面
     *
     * @return
     */
    @RequestMapping(value = "toUpdate")
    @RequiresPermissions(value = "attendance:data:update")
    public String toUpdate(Model model,
                           @RequestParam(value = "id", required = true) String id) {
        TAttendance attendance = attendanceService.getOne(id);
        model.addAttribute("attendance", attendance);
        model.addAttribute("now", new Date());
        return "hydra_easyui/attendance/update";
    }

    /**
     * 编辑考勤记录
     *
     * @param attendance
     * @return
     */
    @RequestMapping(value = "update")
    @ResponseBody
    public Object update(TAttendance attendance,
                         @RequestParam(value = "beginTime1", required = false) Date beginTime1) {
        if (TAttendance.PASS.equals(attendance.getStatus())) {
            throw new BusinessException("已审批通过的考勤记录无法修改！");
        }
        if (beginTime1 != null) {
            beginTime1 = "am".equals(attendance.getApm()) ?
                    DateUtils.setHours(beginTime1, 8) : DateUtils.setHours(beginTime1, 14);
            attendance.setBeginTime(beginTime1);
        } else {
            attendance.setApm(null);
        }
        TAttendance att = attendanceService.updateAttendance(attendance);
        LoggerHelper.logInfo("编辑了考勤登记‘{}’", att.getRemark());
        return JsonFilter.doPropertyFilter(att, new PropertyCollection()
                .addProperties("id", "remark"));
    }

    /**
     * 到编辑考勤登记页面
     *
     * @return
     */
    @RequestMapping(value = "toView")
    public String toView(Model model,
                         @RequestParam(value = "id", required = true) String id) {
        TAttendance attendance = attendanceService.getOne(id);
        model.addAttribute("records", attendanceService.getRecords(attendance));
        model.addAttribute("attendance", attendance);
        return "hydra_easyui/attendance/view";
    }

    /**
     * 到考勤登记条件搜素页面
     *
     * @return
     */
    @RequestMapping(value = "toSearch")
    @RequiresPermissions(value = "attendance:data:update")
    public String toSearch() {
        return "hydra_easyui/attendance/search";
    }

    /**
     * 剩余天数提示
     *
     * @param reasonId
     * @param userId
     * @return
     */
    @RequestMapping(value = "prompt")
    @ResponseBody
    public Object prompt(@RequestParam(value = "reasonId", required = true) String reasonId,
                         @RequestParam(value = "userId", required = true) String userId) {
        TDirectory reason = directoryService.getOne(reasonId);
        SysUserMember user = userService.findOne(userId);
        JSONObject json = new JSONObject();
        if (StringUtils.isNotBlank(reason.getDirDescription())) {
            double configDays = Double.valueOf(reason.getDirDescription());
            SearchAttendanceCondition condition = new SearchAttendanceCondition();
            condition.setReason(reason);
            condition.setUserId(userId);
            condition.setYear(DateUtils.formatDate(new Date(), "yyyy"));
            List<TAttendance> attendances = attendanceService.findAll(condition, null).getContent();
            String msg;
            if (Arrays.asList("公干", "零星事假", "加班").contains(reason.getDirValue())) {
                double hours = attendanceService.countHours(attendances);
                hours = (configDays * hourOfDay - hours > 0) ? (configDays * hourOfDay - hours) : 0;
                msg = "约" + ((int) hours) / ((int) hourOfDay) + "天" + ((int) hours) % ((int) hourOfDay) + "小时";
            } else {
                double days = attendanceService.countDays(attendances, condition);
                double remainDays = (configDays - days > 0) ? (configDays - days) : 0;
                msg = (remainDays == (int) remainDays ? (int) remainDays + "" : remainDays + "") + "天";
            }
            json.put("msg", "(" + user.getUserName() + "的" + reason.getDirValue() + "天数还剩" + msg + ")");
        }
        return json;
    }


    private double hoursToDays(double hours, double hourOfDay) {
//        return Math.round(hours/(hourOfDay/2))*0.5
        //大于等于4小时算半天，大于等于8小时算一天
        return (int) (hours / (hourOfDay / 2)) * 0.5;
    }

    /**
     * 导出审批记录
     *
     * @return
     */
    @RequestMapping(value = "exportAppro")
    @RequiresPermissions(value = "attendance:appro:data:export")
    public String exportAppro(Model model, HttpServletRequest request, HttpServletResponse response) throws IOException {
        List<TApproRecord> approRecords = attendanceService.approRecords();
        ExportBuilder budgetExportBuilder = new ExportBuilder();
        budgetExportBuilder.addColumn(ExportColumn.normal("考勤类别", "tAttendance.reason.dirValue"));
        budgetExportBuilder.addColumn(ExportColumn.normal("考勤人员", "tAttendance.applyUser.userName"));
        budgetExportBuilder.addColumn(ExportColumn.normal("考勤开始时间", "tAttendance.beginTime"));
        budgetExportBuilder.addColumn(ExportColumn.normal("考勤结束时间", "tAttendance.endTime"));
        budgetExportBuilder.addColumn(ExportColumn.normal("审批人", "sysUserMember.userName"));
        budgetExportBuilder.addColumn(ExportColumn.normal("审批时间", "approDate"));
        budgetExportBuilder.addColumn(ExportColumn.converter("审批结果", new ColumnConverter<String, TApproRecord>() {
            public String convert(TApproRecord column) {
                return "1".equals(column.getApproStatus()) ? "同意" : "拒绝";
            }
        }));
        String title = "审批记录表";
        byte[] bytes = ExcelUtils.export(title, approRecords, budgetExportBuilder);
        WebInput.WebOutput out = new WebInput(request).getWebOutput(response);
        out.sendFile(bytes,
                title + "审批记录表.xls", null, true, 30 * 24 * 60 * 60, true, false);
        out.flush();
        return null;
    }

    /**
     * 到数据统计页面
     *
     * @return
     */
    @RequestMapping(value = "toCountList")
    @RequiresPermissions(value = "attendance:data:countList")
    public String toCountList(Model model) {
//        LoggerHelper.logInfo("查看了数据统计");
        model.addAttribute("now", Calendar.getInstance().get(Calendar.YEAR));
//        model.addAttribute("depList", directoryService.findDirectories("DIRECTORY_DEP_TYPE"));
        SearchOrganizationCondition orgCondition = new SearchOrganizationCondition();
        orgCondition.setAvailable(BaseConstant.INTEGER_TRUE);
        model.addAttribute("orgList", organizationService.findAll(orgCondition, null).getContent());
        model.addAttribute("reasonList", directoryService.findDirectoriesByOrder(DirectoryType.valueOf("DIRECTORY_REASON_TYPE")));
        return "hydra_easyui/attendance/countList";
    }

    /**
     * 查询数据统计列表json
     *
     * @param condition
     * @param pageSize
     * @param pageNumber
     * @return
     */
    @RequestMapping(value = "countList")
    @ResponseBody
    public Object countList(
            SearchAttendanceCondition condition,
            @RequestParam(value = "rows", defaultValue = "10", required = false) Integer pageSize,
            @RequestParam(value = "page", defaultValue = "1", required = false) Integer pageNumber) {
        Pageable pageable = PageUtils.buildPageRequest(pageNumber, pageSize, "createTime", "desc");
        Page<TAttendance> page = attendanceService.findAll(condition, pageable);
        return page;
    }

    /**
     * 到个人考勤数据统计页面
     *
     * @return
     */
    @RequestMapping(value = "toSelfCountList")
    @RequiresPermissions(value = "attendance:data:selfCountList")
    public String toSelfCountList(Model model) {
//        LoggerHelper.logInfo("查看了数据统计");
        model.addAttribute("now", Calendar.getInstance().get(Calendar.YEAR));
        model.addAttribute("reasonList", directoryService.findDirectoriesByOrder(DirectoryType.valueOf("DIRECTORY_REASON_TYPE")));
        return "hydra_easyui/attendance/selfCountList";
    }

    /**
     * 查询个人考勤数据统计列表json
     *
     * @param condition
     * @param pageSize
     * @param pageNumber
     * @return
     */
    @RequestMapping(value = "selfCountList")
    @ResponseBody
    public Object selfCountList(
            SearchAttendanceCondition condition, LoginUser loginUser,
            @RequestParam(value = "rows", defaultValue = "10", required = false) Integer pageSize,
            @RequestParam(value = "page", defaultValue = "1", required = false) Integer pageNumber) {
        Pageable pageable = PageUtils.buildPageRequest(pageNumber, pageSize, "createTime", "desc");
        condition.setUserId(loginUser.getId());
        Page<TAttendance> page = attendanceService.findAll(condition, pageable);
        return page;
    }


    /**
     * 考勤数据导出
     *
     * @param response
     * @param condition
     * @throws IOException
     */
    @RequestMapping("export")
    @RequiresPermissions("attendance:data:export")
    public void export(HttpServletResponse response, SearchAttendanceCondition condition) throws IOException {
        Pageable pageable = PageUtils.buildPageRequest(1, 999, new OrderCollection()
                .addOrder(Sort.Direction.ASC, "applyUser.orderNo")
                .addOrder(Sort.Direction.DESC, "createTime"));
        List<TAttendance> list = attendanceService.findAll(condition, pageable).getContent();
        List<String> results = QueryHelper.doQueryProperties(list, true, new QueryHelper.PropertyReader<TAttendance, String>() {

            public String read(TAttendance attendance) {
                return attendance.getReason().getDirValue() + ":" + attendance.getRemark();
            }
        });
        String fileName = "";
        if (StringUtils.isNotBlank(condition.getYear())) {
            fileName += condition.getYear() + "年";
        }
        if (StringUtils.isNotBlank(condition.getMonth())) {
            fileName += condition.getMonth() + "月";
        }
        if (StringUtils.isNotBlank(condition.getOrgId())) {
            fileName += organizationService.findOne(condition.getOrgId()).getOrgName();
        }
        if (StringUtils.isNotBlank(condition.getUserId())) {
            fileName += userService.findOne(condition.getUserId()).getUserName();
        }
        fileName += "考勤记录.xls";
        fileName = URLEncoder.encode(fileName, "UTF-8");
        condition.getExcelInfo().setSortNum(true);
        HSSFWorkbook wb = ExcelDataWriter.exportExcel(condition.getExcelInfo(), list);
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        ServletOutputStream out = response.getOutputStream();
        LoggerHelper.logInfo("执行了考勤记录导出{}条，分别为{}", list.size(), StringUtils.join(results, ","));
        wb.write(out);
        out.flush();
        out.close();
    }

    /**
     * 考勤数据统计导出
     *
     * @param response
     * @param condition
     * @throws IOException
     */
    @RequestMapping("exportCount")
    @RequiresPermissions("attendance:data:export")
    public void exportCount(HttpServletResponse response, SearchAttendanceCondition condition) throws IOException {
        String fileName = "";
        if (StringUtils.isNotBlank(condition.getYear())) {
            fileName += condition.getYear() + "年";
        }
        if (StringUtils.isNotBlank(condition.getMonth())) {
            fileName += condition.getMonth() + "月";
        }
        if (StringUtils.isNotBlank(condition.getOrgId())) {
            fileName += organizationService.findOne(condition.getOrgId()).getOrgName();
        }
        if (StringUtils.isNotBlank(condition.getUserId())) {
            fileName += userService.findOne(condition.getUserId()).getUserName();
        }
        String str = fileName;
        fileName += "考勤统计.xls";
        LoggerHelper.logInfo("执行了{}考勤统计导出", str);

        List<TAttendance> list = attendanceService.findAll(condition, null).getContent();
        List<SysUserMember> users = userService.findAllByOrderNoASC();
        List<CountExport> counts = new ArrayList<CountExport>();
        for (final SysUserMember user : users) {
            List<TAttendance> gonggan = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<TAttendance>() {

                public boolean match(TAttendance attendance) {
                    return user.equals(attendance.getApplyUser()) && "公干".equals(attendance.getReason().getDirValue());
                }
            });
            List<TAttendance> lingxing = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<TAttendance>() {

                public boolean match(TAttendance attendance) {
                    return user.equals(attendance.getApplyUser()) && "零星事假".equals(attendance.getReason().getDirValue());
                }
            });
            List<TAttendance> jiaban = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<TAttendance>() {

                public boolean match(TAttendance attendance) {
                    return user.equals(attendance.getApplyUser()) && "加班".equals(attendance.getReason().getDirValue());
                }
            });
            List<TAttendance> huanxiu = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<TAttendance>() {

                public boolean match(TAttendance attendance) {
                    return user.equals(attendance.getApplyUser()) && "换休".equals(attendance.getReason().getDirValue());
                }
            });
            List<TAttendance> chuchai = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<TAttendance>() {

                public boolean match(TAttendance attendance) {
                    return user.equals(attendance.getApplyUser()) && "出差".equals(attendance.getReason().getDirValue());
                }
            });
            List<TAttendance> youxin = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<TAttendance>() {

                public boolean match(TAttendance attendance) {
                    return user.equals(attendance.getApplyUser()) && "有薪事假".equals(attendance.getReason().getDirValue());
                }
            });
            List<TAttendance> wuxin = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<TAttendance>() {

                public boolean match(TAttendance attendance) {
                    return user.equals(attendance.getApplyUser()) && "无薪事假".equals(attendance.getReason().getDirValue());
                }
            });
            List<TAttendance> bingjia = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<TAttendance>() {

                public boolean match(TAttendance attendance) {
                    return user.equals(attendance.getApplyUser()) && "病假".equals(attendance.getReason().getDirValue());
                }
            });
            List<TAttendance> chanjia = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<TAttendance>() {

                public boolean match(TAttendance attendance) {
                    return user.equals(attendance.getApplyUser()) && "产假".equals(attendance.getReason().getDirValue());
                }
            });
            List<TAttendance> hunsang = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<TAttendance>() {

                public boolean match(TAttendance attendance) {
                    return user.equals(attendance.getApplyUser()) && "婚丧假".equals(attendance.getReason().getDirValue());
                }
            });
            List<TAttendance> gongshang = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<TAttendance>() {

                public boolean match(TAttendance attendance) {
                    return user.equals(attendance.getApplyUser()) && "工伤假".equals(attendance.getReason().getDirValue());
                }
            });
            List<TAttendance> gongling = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<TAttendance>() {

                public boolean match(TAttendance attendance) {
                    return user.equals(attendance.getApplyUser()) && "工龄假".equals(attendance.getReason().getDirValue());
                }
            });
            List<TAttendance> zhicheng = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<TAttendance>() {

                public boolean match(TAttendance attendance) {
                    return user.equals(attendance.getApplyUser()) && "职称假".equals(attendance.getReason().getDirValue());
                }
            });
            List<TAttendance> youhai = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<TAttendance>() {

                public boolean match(TAttendance attendance) {
                    return user.equals(attendance.getApplyUser()) && "有害假".equals(attendance.getReason().getDirValue());
                }
            });
            List<TAttendance> tanqin = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<TAttendance>() {

                public boolean match(TAttendance attendance) {
                    return user.equals(attendance.getApplyUser()) && "探亲假".equals(attendance.getReason().getDirValue());
                }
            });
            List<TAttendance> holiday = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<TAttendance>() {

                public boolean match(TAttendance attendance) {
                    return user.equals(attendance.getApplyUser()) &&
                            Arrays.asList("有薪事假", "无薪事假", "病假", "产假", "婚丧假", "工伤假", "工龄假",
                                    "职称假", "有害假", "探亲假").contains(attendance.getReason().getDirValue());
                }
            });
            CountExport count = new CountExport();
            count.setUser(user.getUserName());
//            count.setOrg("504");
//            count.setOrg(user.getSysOrganizations().get(0).getDepBelong().getDirValue());
            count.setGroup(user.getOrgsDescription());
            count.setGongganH(attendanceService.countHours(gonggan) + "");
//            count.setGongganD(Math.round(attendanceService.countHours(gonggan)/(hourOfDay/2))*0.5+"");
            count.setGongganD(hoursToDays(Double.valueOf(count.getGongganH()), hourOfDay) + "");
            count.setLingxingH(attendanceService.countHours(lingxing) + "");
            count.setLingxingD(hoursToDays(Double.valueOf(count.getLingxingH()), hourOfDay) + "");
            count.setJiabanH(attendanceService.countHours(jiaban) + "");
            count.setJiabanD(hoursToDays(Double.valueOf(count.getJiabanH()), hourOfDay1) + "");//加班按7小时一天算
            count.setHuanxiu(attendanceService.countDays(huanxiu, condition) + "");
            count.setChuchai(attendanceService.countDays(chuchai, condition) + "");
            count.setYouxinshijia(attendanceService.countDays(youxin, condition) + "");
            count.setWuxinshijia(attendanceService.countDays(wuxin, condition) + "");
            count.setBingjia(attendanceService.countDays(bingjia, condition) + "");
            count.setChanjia(attendanceService.countDays(chanjia, condition) + "");
            count.setHunsangjia(attendanceService.countDays(hunsang, condition) + "");
            count.setGongshangjia(attendanceService.countDays(gongshang, condition) + "");
            count.setGonglingjia(attendanceService.countDays(gongling, condition) + "");
            count.setZhichengjia(attendanceService.countDays(zhicheng, condition) + "");
            count.setYouhaijia(attendanceService.countDays(youhai, condition) + "");
            count.setTanqinjia(attendanceService.countDays(tanqin, condition) + "");
            count.setHoliday1((attendanceService.countDays(holiday, condition) + Double.valueOf(count.getLingxingD())) + "");
            count.setHoliday2(attendanceService.countDays(holiday, condition) + "");
            counts.add(count);
        }
        condition.getExcelInfo().setSortNum(true);
        HSSFWorkbook wb = ExcelDataWriter.exportExcel(condition.getExcelInfo(), counts);
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        ServletOutputStream out = response.getOutputStream();
        wb.write(out);
        out.flush();
        out.close();
    }

    /**
     * 考勤汇总导出
     *
     * @param response
     * @param condition
     * @throws IOException
     */
    @RequestMapping("exportSumCount")
    @RequiresPermissions("attendance:data:export")
    public void exportSumCount(HttpServletResponse response, SearchAttendanceCondition condition, final boolean lx) throws IOException {
        String fileName = "";
        if (StringUtils.isNotBlank(condition.getYear())) {
            fileName += condition.getYear() + "年";
        }
        if (StringUtils.isNotBlank(condition.getMonth())) {
            fileName += condition.getMonth() + "月";
        }
        if (StringUtils.isNotBlank(condition.getOrgId())) {
            fileName += organizationService.findOne(condition.getOrgId()).getOrgName();
        }
        String str = fileName;
        fileName += !lx ? "职工考勤汇总表.xls" : "职工考勤汇总表（含零星事假）.xls";
        LoggerHelper.logInfo("执行了{}考勤统计导出", str);

        condition.setUserId(null);
        List<TAttendance> list = attendanceService.findAll(condition, null).getContent();
        List<SysUserMember> users = userService.findAllByOrderNoASC();
        List<CountExport> counts = new ArrayList<CountExport>();
        for (final SysUserMember user : users) {
            List<TAttendance> sum = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<TAttendance>() {

                public boolean match(TAttendance attendance) {
                    if (lx) {
                        return user.equals(attendance.getApplyUser()) &&
                                !Arrays.asList("公干", "加班", "换休", "出差").contains(attendance.getReason().getDirValue());
                    } else {
                        return user.equals(attendance.getApplyUser()) &&
                                !Arrays.asList("公干", "加班", "换休", "出差", "零星事假").contains(attendance.getReason().getDirValue());
                    }
                }
            });
            if (sum.size() != 0) {
                Collections.sort(sum, new Comparator<TAttendance>() {

                    public int compare(TAttendance o1, TAttendance o2) {
                        return o1.getBeginTime().compareTo(o2.getBeginTime());
                    }
                });
                List<TAttendance> lingX = QueryHelper.doFilter(sum, new QueryHelper.MatchWorker<TAttendance>() {

                    public boolean match(TAttendance attendance) {
                        return "零星事假".equals(attendance.getReason().getDirValue());
                    }
                });
                List<TAttendance> noLingX = QueryHelper.doFilter(sum, new QueryHelper.MatchWorker<TAttendance>() {

                    public boolean match(TAttendance attendance) {
                        return !"零星事假".equals(attendance.getReason().getDirValue());
                    }
                });
                double linXDays = hoursToDays(attendanceService.countHours(lingX), hourOfDay);
                if (noLingX.size() != 0 || (noLingX.size() == 0 && linXDays != 0)) {
                    CountExport count = new CountExport();
                    count.setUser(user.getUserName());
                    count.setOrg("504");
//                    count.setOrg(user.getSysOrganizations().get(0).getDepBelong().getDirValue());
                    count.setGroup(user.getOrgsDescription());
                    double totalTime = !lx ? attendanceService.countDays(sum, condition) :
                            attendanceService.countDays(noLingX, condition) + linXDays;
                    count.setTotalTime(totalTime + "天");
                    List<String> reasons = QueryHelper.doQueryProperties(linXDays != 0 ? sum : noLingX, true, new QueryHelper.PropertyReader<TAttendance, String>() {

                        public String read(TAttendance attendance) {
                            return attendance.getReason().getDirValue();
                        }
                    });
                    count.setReasonStr(StringUtils.join(new ArrayList<String>(new LinkedHashSet<String>(reasons)), "、"));
                    count.setTimeStr(attendanceService.getTimeRange(linXDays != 0 ? sum : noLingX, condition));
                    counts.add(count);
                }
            }
        }
        condition.getExcelInfo().setSortNum(true);
        HSSFWorkbook wb = ExcelDataWriter.exportExcel(condition.getExcelInfo(), counts);
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        ServletOutputStream out = response.getOutputStream();
        wb.write(out);
        out.flush();
        out.close();
    }

    /**
     * 加班汇总导出
     *
     * @param response
     * @param condition
     * @throws IOException
     */
    @RequestMapping("exportSumOverwork")
    @RequiresPermissions("attendance:data:export")
    public void exportSumOverwork(HttpServletResponse response, SearchAttendanceCondition condition) throws IOException {
        String fileName = "";
        if (StringUtils.isNotBlank(condition.getYear())) {
            fileName += condition.getYear() + "年";
        }
        if (StringUtils.isNotBlank(condition.getOrgId())) {
            fileName += organizationService.findOne(condition.getOrgId()).getOrgName();
        }
        String str = fileName;
        fileName += "加班工时汇总表.xls";
        LoggerHelper.logInfo("执行了{}考勤统计导出", str);

        condition.setMonth(null);
        condition.setUserId(null);
        String[] seasons = {"一季度", "二季度", "三季度", "四季度"};
        Map<String, List<CountExport>> sheets = new LinkedHashMap<String, List<CountExport>>();
        for (int i = 1; i <= 4; i++) {
            condition.setSeason(i + "");
            List<TAttendance> list = attendanceService.findAll(condition, null).getContent();
            List<SysUserMember> users = userService.findAllByOrderNoASC();
            List<CountExport> counts = new ArrayList<CountExport>();
            for (final SysUserMember user : users) {
                List<TAttendance> jiaban = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<TAttendance>() {

                    public boolean match(TAttendance attendance) {
                        return user.equals(attendance.getApplyUser()) && "加班".equals(attendance.getReason().getDirValue());
                    }
                });
                if (jiaban.size() > 0) {
                    CountExport count = new CountExport();
                    count.setUser(user.getUserName());
//                    count.setOrg("504");
//                    count.setOrg(user.getSysOrganizations().get(0).getDepBelong().getDirValue());
                    count.setGroup(user.getOrgsDescription());
                    count.setJiabanH(attendanceService.countHours(jiaban) + "");
                    counts.add(count);
                }
            }
            sheets.put(seasons[i - 1], counts);
        }
        condition.getExcelInfo().setSortNum(true);
        HSSFWorkbook wb = ExcelDataWriter.exportExcelSheets(condition.getExcelInfo(), sheets);
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        ServletOutputStream out = response.getOutputStream();
        wb.write(out);
        out.flush();
        out.close();
    }

    /**
     * 数据统计-个人单饼图
     *
     * @param condition
     * @return
     */
    @RequestMapping(value = "selfCountPie")
    @ResponseBody
    public Object selfCountPie(SearchAttendanceCondition condition) {
        JSONObject result = new JSONObject();

        JSONArray title = new JSONArray();
        JSONArray content = new JSONArray();
        List<TAttendance> list = attendanceService.findAll(condition, null).getContent();
        List<TDirectory> reasons = directoryService.findDirectoriesByOrder(DirectoryType.valueOf("DIRECTORY_REASON_TYPE"));
        for (final TDirectory reason : reasons) {
            title.add(reason.getDirValue());
            List<TAttendance> attendances = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<TAttendance>() {

                public boolean match(TAttendance attendance) {
                    return reason.equals(attendance.getReason());
                }
            });
            double days;
            if (Arrays.asList("公干", "零星事假", "加班").contains(reason.getDirValue())) {
                double hours = attendanceService.countHours(attendances);
                double hOfd = "加班".equals(reason.getDirValue()) ? hourOfDay1 : hourOfDay;//加班按7小时一天算
                days = (double) Math.round((hours / hOfd) * 10) / 10;
            } else {
                days = attendanceService.countDays(attendances, condition);
            }
            if (days != 0) {
                JSONObject data = new JSONObject();
                data.put("name", reason.getDirValue());
                data.put("value", days);
                content.add(data);
            }
        }
        result.put("title", title);
        result.put("content", content);

        return result;
    }

    /**
     * 数据统计-堆积柱图
     *
     * @param condition
     * @return
     */
    @RequestMapping(value = "countBar")
    @ResponseBody
    public Object countBar(final SearchAttendanceCondition condition) {
        JSONObject result = new JSONObject();
        List<TAttendance> list = attendanceService.findAll(condition, null).getContent();
        List<TDirectory> reasons = directoryService.findDirectoriesByOrder(DirectoryType.valueOf("DIRECTORY_REASON_TYPE"));
        List<Object> legends = QueryHelper.doQueryProperties(reasons, true, new QueryHelper.PropertyReader<TDirectory, Object>() {

            public Object read(TDirectory tDirectory) {
                return tDirectory.getDirValue();
            }
        });
        result.put("legend", new JSONArray(legends));

        if (StringUtils.isNotBlank(condition.getUserId())) {
            result.put("chartType", "pie");
            JSONArray data = new JSONArray();
            for (final TDirectory reason : reasons) {
                JSONObject dataItem = new JSONObject();
                List<TAttendance> attendances = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<TAttendance>() {

                    public boolean match(TAttendance attendance) {
                        return reason.equals(attendance.getReason())
                                && condition.getUserId().equals(attendance.getApplyUser().getId());
                    }
                });
                if (attendances.size() != 0) {
                    dataItem.put("name", reason.getDirValue());
                    if (Arrays.asList("公干", "零星事假", "加班").contains(reason.getDirValue())) {
                        double hours = attendanceService.countHours(attendances);
                        double hOfd = "加班".equals(reason.getDirValue()) ? hourOfDay1 : hourOfDay;//加班按7小时一天算
                        dataItem.put("value", (double) Math.round((hours / hOfd) * 10) / 10);
                    } else {
                        dataItem.put("value", attendanceService.countDays(attendances, condition));
                    }
                }
                data.add(dataItem);
            }
            result.put("data", data);
        } else {
            if (StringUtils.isBlank(condition.getOrgId())) {
                SearchOrganizationCondition orgCondition = new SearchOrganizationCondition();
                orgCondition.setAvailable(BaseConstant.INTEGER_TRUE);
                List<SysOrganization> orgList = organizationService.findAll(orgCondition, null).getContent();
                List<Object> orgNames = QueryHelper.doQueryProperties(orgList, true, new QueryHelper.PropertyReader<SysOrganization, Object>() {

                    public Object read(SysOrganization org) {
                        return org.getOrgName();
                    }
                });
                result.put("xAxis", new JSONArray(orgNames));
                JSONArray series = new JSONArray();
                for (final TDirectory reason : reasons) {
                    JSONObject ser = new JSONObject();
                    ser.put("name", reason.getDirValue());
                    ser.put("type", "bar");
                    if (!"加班".equals(reason.getDirValue())) {
                        ser.put("stack", "考勤统计");
                    }
                    List<Object> data = new ArrayList<Object>();
                    for (final SysOrganization org : orgList) {
                        List<TAttendance> attendances = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<TAttendance>() {

                            public boolean match(TAttendance attendance) {
                                return org.equals(attendance.getApplyUser().getSysOrganizations().get(0))
                                        && reason.equals(attendance.getReason());
                            }
                        });
                        if (Arrays.asList("公干", "零星事假", "加班").contains(reason.getDirValue())) {
                            double hours = attendanceService.countHours(attendances);
                            double hOfd = "加班".equals(reason.getDirValue()) ? hourOfDay1 : hourOfDay;//加班按7小时一天算
                            data.add((double) Math.round((hours / hOfd) * 10) / 10);
                        } else {
                            data.add(attendanceService.countDays(attendances, condition));
                        }
                    }
                    ser.put("data", new JSONArray(data));
                    series.add(ser);
                }
                result.put("series", series);
            } else {
                SearchUserCondition userCondition = new SearchUserCondition();
                userCondition.setAvailable(BaseConstant.INTEGER_TRUE);
                userCondition.setOrgId(condition.getOrgId());
                List<SysUserMember> userList = userService.findAll(userCondition);
                List<Object> userNames = QueryHelper.doQueryProperties(userList, true, new QueryHelper.PropertyReader<SysUserMember, Object>() {

                    public Object read(SysUserMember user) {
                        return user.getUserName();
                    }
                });
                if (userList.size() > 10) {
                    result.put("dataZoom", JSONObject.parseObject("{show : true,realtime: true,start : 0,end : 50,zoomLock: true}"));
                }
                result.put("xAxis", new JSONArray(userNames));
                JSONArray series = new JSONArray();
                for (final TDirectory reason : reasons) {
                    JSONObject ser = new JSONObject();
                    ser.put("name", reason.getDirValue());
                    ser.put("type", "bar");
                    if (!"加班".equals(reason.getDirValue())) {
                        ser.put("stack", "考勤统计");
                    }
                    List<Object> data = new ArrayList<Object>();
                    for (final SysUserMember user : userList) {
                        List<TAttendance> attendances = QueryHelper.doFilter(list, new QueryHelper.MatchWorker<TAttendance>() {

                            public boolean match(TAttendance attendance) {
                                return user.equals(attendance.getApplyUser()) && reason.equals(attendance.getReason());
                            }
                        });
                        if (Arrays.asList("公干", "零星事假", "加班").contains(reason.getDirValue())) {
                            double hours = attendanceService.countHours(attendances);
                            double hOfd = "加班".equals(reason.getDirValue()) ? hourOfDay1 : hourOfDay;//加班按7小时一天算
                            data.add((double) Math.round((hours / hOfd) * 10) / 10);
                        } else {
                            data.add(attendanceService.countDays(attendances, condition));
                        }
                    }
                    ser.put("data", new JSONArray(data));
                    series.add(ser);
                }
                result.put("series", series);
            }
        }

        return result;
    }

//    /**
//     * 加班数据导出
//     * @param response
//     * @param condition
//     * @throws IOException
//     */
//    @RequestMapping("exportOverWork")
//    @RequiresPermissions("attendance:data:export")
//    public void exportOverWork(HttpServletResponse response, SearchAttendanceCondition condition) throws IOException {
//        Pageable pageable = PageUtils.buildPageRequest(1, 10, "applyUser.orderNo", "asc");
//        condition.setReason(directoryService.findDirectories("DIRECTORY_REASON_TYPE", "加班"));
//        List<TAttendance> list = attendanceService.findAll(condition, pageable).getContent();
//        List<String> results = QueryHelper.doQueryProperties(list, true, new QueryHelper.PropertyReader<TAttendance, String>() {
//
//            public String read(TAttendance attendance) {
//                return attendance.getProjectCode() + ":" + attendance.getRemark();
//            }
//        });
//        String fileName = "";
//        if (StringUtils.isNotBlank(condition.getYear())){
//            fileName += condition.getYear() + "年";
//        }
//        if (StringUtils.isNotBlank(condition.getMonth())){
//            fileName += condition.getMonth() + "月";
//        }
//        if (StringUtils.isNotBlank(condition.getOrgId())){
//            fileName += organizationService.findOne(condition.getOrgId()).getOrgName();
//        }
//        if (StringUtils.isNotBlank(condition.getUserId())){
//            fileName += userService.findOne(condition.getUserId()).getUserName();
//        }
//        fileName += "加班数据.xls";
//        fileName = URLEncoder.encode(fileName, "UTF-8");
//        condition.getExcelInfo().setSortNum(true);
//        HSSFWorkbook wb = ExcelDataWriter.exportExcel(condition.getExcelInfo(), list);
//        response.setContentType("application/octet-stream");
//        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
//        ServletOutputStream out = response.getOutputStream();
//        LoggerHelper.logInfo("执行了加班数据导出{}条，分别为{}", list.size(), StringUtils.join(results,","));
//        wb.write(out);
//        out.flush();
//        out.close();
//    }

//    /**
//     * 数据统计-嵌套环饼图
//     * @param condition
//     * @return
//     */
//    @RequestMapping(value = "count")
//    @ResponseBody
//    public Object count(SearchAttendanceCondition condition){
//        JSONObject result = new JSONObject();
//
//        JSONArray out = new JSONArray();
//        List<TDirectory> reasons = directoryService.findDirectories("DIRECTORY_REASON_TYPE");
//        for (TDirectory reason : reasons) {
//            condition.setReason(reason);
//            List<TAttendance> attendances = attendanceService.findAll(condition, null).getContent();
//            double days = attendanceService.countDays(attendances, condition);
//            if (days != 0){
//                JSONObject data = new JSONObject();
//                data.put("name", reason.getDirValue());
//                data.put("value", days);
//                out.add(data);
//            }
//        }
//        result.put("out", out);
//
//        JSONArray in = new JSONArray();
//        condition.setReason(null);
//        if (StringUtils.isBlank(condition.getOrgId())){
//            SearchOrganizationCondition orgCondition = new SearchOrganizationCondition();
//            orgCondition.setAvailable(BaseConstant.INTEGER_TRUE);
//            List<SysOrganization> orgList = organizationService.findAll(orgCondition, null).getContent();
//            for (SysOrganization org : orgList) {
//                condition.setOrgId(org.getId());
//                List<TAttendance> attendances = attendanceService.findAll(condition, null).getContent();
//                double days = attendanceService.countDays(attendances, condition);
//                if (days != 0){
//                    JSONObject data = new JSONObject();
//                    data.put("name", org.getOrgName());
//                    data.put("value", days);
//                    in.add(data);
//                }
//            }
//        }else {
//            if (StringUtils.isNotBlank(condition.getUserId())){
//                List<TAttendance> attendances = attendanceService.findAll(condition, null).getContent();
//                double days = attendanceService.countDays(attendances, condition);
//                if (days != 0){
//                    JSONObject data = new JSONObject();
//                    SysUserMember user = userService.findOne(condition.getUserId());
//                    data.put("name", user.getUserName());
//                    data.put("value", days);
//                    in.add(data);
//                }
//            }else {
//                List<SysUserMember> users = userService.queryUserOfOrganization(condition.getOrgId());
//                for (SysUserMember user : users) {
//                    condition.setUserId(user.getId());
//                    List<TAttendance> attendances = attendanceService.findAll(condition, null).getContent();
//                    double days = attendanceService.countDays(attendances, condition);
//                    if (days != 0){
//                        JSONObject data = new JSONObject();
//                        data.put("name", user.getUserName());
//                        data.put("value", days);
//                        in.add(data);
//                    }
//                }
////                SysOrganization org = organizationService.findOne(condition.getOrgId());
////                data.put("name", org.getOrgName());
//            }
//        }
//        result.put("in", in);
//
//        return result;
//    }

}
